/***
 * 富文本的表格封装
 * @Author: kevin.huang 
 * ****/
//表格控件
function Table(edit) {
    this.edit = edit;
    this.className = "table";
    this.selectBackground = "#F0F0F0";
    var _this = this;
    this.clickTd = undefined;
    this.movingTd = undefined;
    this.mutilSelectBackground = {};
    this.menu = getSingleton("TableProps", edit);
    this.width = undefined;
    this.height = undefined;
    this.onlyUpdateHeight = false;
    this.onlyUpdateWidth = false;
    this.selectTdArray = [];
}
Table.prototype = {
    constructor: Table,
    initByJq: function (jqObj) {
        this.table = jqObj;
        this.jqObj = this.table;
        this.tbody = this.table.children();
        var events = this._getTdEvents();
        this.resetTableIndex(function (td) {
            td.on(events);
        });
        var _this = this;
        setTimeout(function () {
            _this.reSize(true);
        });
        this.contenteditableTxt = this.table.parent();
        //根据k_edit_table_selected_td 创建 mutilSelectBackground 
        _this.mutilSelectBackground = {};
        var tdArray = this.tbody.children().children("td.k_edit_table_selected_td");
        var cssTdArray = [];
        tdArray.each(function () {
            var td = $(this);
            var bgColor = td.attr("bgcolor");
            _this.mutilSelectBackground[td.attr("row") + "_" + td.attr("col")] = {
                "td": td,
                "background": bgColor
            };
            cssTdArray.push(td);
        });
        this.selectTdArray = cssTdArray;
        this.jqObj.data("object", this); //记录对应的对象实例
        fixIeResizeBug(this.jqObj[0]);
        return this;
    },
    resetTableIndex: function (onForeachFn) {
        var trs = this.tbody.children();
        var posArray = [];
        var posMap = {};
        trs.each(function () {
            var tr = $(this);
            tr.children().each(function () {
                var td = $(this);
                var ofs = td.offset();
                if (!posMap[ofs.left]) {
                    posMap[ofs.left] = 1;
                    posArray.push(ofs.left);
                }
            });
        });
        posArray.sort(function (a, b) {
            return a - b;
        });
        var colNum = 0;
        var call = typeof onForeachFn === "function";
        trs.each(function (j) {
            var tr = $(this);
            tr.attr("id", "row_" + j);
            var tdCount = 0;
            tr.children().each(function (i) {
                tdCount++;
                var td = $(this);
                var colspan = td.attr("colspan");
                if (colspan) {
                    colspan = parseInt(colspan) - 1;
                    while (colspan > 0) {
                        tdCount++;
                        colspan--;
                    }
                }
                var left = td.offset().left;
                var idx;
                for (var k = 0, len = posArray.length; k < len; ++k) {
                    if ((left - 2) <= posArray[k] && posArray[k] <= (left + 2)) {//兼容1 像数差异问题
                        idx = k;
                        break;
                    }
                }
                td.addClass("k_box_size");
                td.attr({
                    "tabindex": 0,
                    "row": j,
                    "col": i,
                    "index": idx
                });
                if (call) {
                    onForeachFn(td);
                }
            });
            if (tdCount > colNum) {
                colNum = tdCount;
            }
        });
        this.rowNum = trs.length;
        this.colNum = colNum;
    },
    init: function (colNum, rowNum) {
        var tdEvents = this._getTdEvents();
        this.table = $("<table  class='k_box_size' style='border-collapse:collapse;width:100%;height:auto;'><tbody></tbody></table>");
        this.jqObj = this.table;
        this.tbody = this.table.children();
        for (var i = 0; i < rowNum; ++i) {
            var tr = this._createTr({
                "id": "row_" + i
            });
            for (var j = 0; j < colNum; ++j) {
                var td = this._createTd({
                    "tabindex": "0",
                    "row": i,
                    "col": j,
                    "index": j
                }, eConfig.table.tdCss);
                tr.append(td);
                td.on(tdEvents);
            }
            this.tbody.append(tr);
        }
        this.colNum = colNum;
        this.rowNum = rowNum;
        var _this = this;
        setTimeout(function () {
            _this._activedFirstTd();
        }, 10);
        _this.jqObj.data("object", _this); //记录对应的对象实例
        fixIeResizeBug(this.jqObj[0]);
        return this;
    },
    _hideAdd: function () {
        if (this.$addBtn) {
            this.$addBtn.hide();
            this.$addBtn.removeData("table");
            this.$addBtn.removeData("target");
        }
    },
    _showAdd: function (target, ofs, title) {
        var _this = this;
        if (!this.$addBtn) {
            this.$addBtn = _getBody().children("#k_edit_table_addbtn");
            if (this.$addBtn.length === 0) {
                var $addBtn = $("<div id='k_edit_table_addbtn' title='" + title + "' style='cursor:pointer;background:none;width:14px;height:14px;top:-1000px;position:absolute;z-index:9999999999;display:none;'><i style='font-size:12px' class='fa fa-plus'></i></div>");
                this.$addBtn = $addBtn.appendTo(_getBody()).click(function () {
                    var $t = $(this);
                    var tabObj = $t.data("table");
                    var itarget = $t.data("target");
                    $t.hide();
                    $t.removeData("table");
                    $t.removeData("target");
                    var srcTd;
                    if (itarget[0].tagName === "TD") {
                        srcTd = tabObj.clickTd;
                        tabObj.clickTd = itarget;
                        tabObj.insertColFn("r");
                        tabObj.clickTd = srcTd;
                    } else {
                        srcTd = tabObj.clickTd;
                        tabObj.clickTd = itarget.children().first();
                        tabObj.insertRowFn("b");
                        tabObj.clickTd = srcTd;
                    }
                });
            }
        }
        this.$addBtn.data("table", this).attr("title", title);
        this.$addBtn.data("target", target);
        this.$addBtn.css(ofs).show();
        clearTimeout(this.addBtnHideTimer);
        this.addBtnHideTimer = setTimeout(function () {
            if (_this.$addBtn) {
                _this.$addBtn.hide();
                _this.$addBtn.removeData("table");
                _this.$addBtn.removeData("target");
            }
        }, 2500);
    },
    _getTdEvents: function () {
        if (!this.tdEvents) {
            var _this = this;
            var splitXPos, splitYPos, splitLine;
            var targetRow, undoData;
            var mutilSelect = false;
            var tdEvents = {
                mouseup: function (e) {
                    var tmpArr = [];
                    if ($.isEmptyObject(_this.mutilSelectBackground)) { //非多选
                        tmpArr.push(_this.clickTd);
                        if (e.which === 3 && e.target.nodeName !== "A") {
                            _this.showMenu(e);
                        } else {//移动功能
                            var td = $(this);
                            var parent = td.parent();
                            while (parent.length > 0) {
                                if (parent[0].tagName === "DIV") {
                                    break;
                                }
                                parent = parent.parent();
                            }
                            var eles = [parent];
                            _this.edit._setMovingTargets(eles, false);
                        }
                    } else {
                        _this.edit.clearUserRange(true);
                        _this.foreachSeletedTds(function (rec) {
                            tmpArr.push(rec.td);
                        });
                        _this.clearClickTd();
                        e["mutils"] = true;
                        _this.showMenu(e);
                    }
                    _this.selectTdArray = tmpArr;
                    _this.edit.clickActivedObject = _this;
                    mutilSelect = false;
                    _this.movingTd = undefined;
                },
                mousemove: function (e) {
                    var td = $(this);
                    var ofs = td.offset();
                    var w = td.outerWidth();
                    var h = td.outerHeight();
                    var endOfs = {
                        top: ofs.top + h,
                        left: ofs.left + w
                    };
                    var row = parseInt(td.attr("row"));
                    var col = parseInt(td.attr("col"));
                    var id = row + "_" + col;
                    if (mutilSelect) {
                        if (!_this.movingTd) {
                            _this.movingTd = td;
                        } else {
                            var movingId = _this.movingTd.attr("row") + "_" + _this.movingTd.attr("col");
                            if (movingId !== id) {
                                _this.movingTd = td;
                                _this.makeSelectedUi();
                                //清除document中的选择区域
                                if (document.selection) {
                                    document.selection.empty();
                                } else if (window.getSelection) {
                                    window.getSelection().removeAllRanges();
                                }
                                return false;
                            }
                        }
                    }
                    targetRow = undefined;
                    splitXPos = undefined;
                    splitYPos = undefined;
                    var mouseX = e.pageX;
                    var mouseY = e.pageY;
                    _this.table.css("cursor", "default");
                    _this.contenteditableTxt.removeAttr("contenteditable");
                    var startXshift = mouseX - ofs.left;
                    var endXshift = endOfs.left - mouseX;
                    if (startXshift <= 5 || endXshift <= 5) {
                        if (startXshift <= 5) {
                            splitXPos = ofs;
                        } else {
                            splitXPos = endOfs;
                        }
                    }
                    if (splitXPos) {
                        _this.table.css("cursor", "w-resize");
                        _this.contenteditableTxt.attr("contenteditable", false);
                    } else { //行高拖动                   
                        var startYshift = mouseY - ofs.top;
                        var endYshift = endOfs.top - mouseY;
                        if (startYshift <= 5 || endYshift <= 5) {
                            var currentRow = td.parent();
                            if (startYshift <= 5) {
                                targetRow = currentRow.prev();
                                splitYPos = {
                                    "top": ofs.top
                                };
                            } else {
                                splitYPos = {
                                    "top": endOfs.top
                                };
                                targetRow = currentRow;
                            }
                            if (splitYPos) {
                                _this.table.css("cursor", "s-resize");
                                _this.contenteditableTxt.attr("contenteditable", false);
                            }
                        }
                    }
                    //检查提示全选按钮
                    var isLastCol = _this.colNum === (col + 1);
                    var isLastRow = _this.rowNum === (row + 1);
                    var mouseOfs = {
                        top: e.pageY,
                        left: e.pageX
                    };
                    if (row === 0) {
                        if (col === 0) {
                            //左上角方向
                            if (e.pageX <= (ofs.left + 50)) {
                                _this._showAnchor({
                                    col: col,
                                    row: row,
                                    isLastRow: isLastRow,
                                    isLastCol: isLastCol
                                }, ofs, endOfs, mouseOfs);
                            } else {
                                _this._hideAnchor();
                            }
                        }
                    } else {
                        _this._hideAnchor();
                    }
                    //快捷插入行列 _showAdd(target, ofs) insertCol insertRow 
                    var tableOfs = _this.table.offset();
                    var insertTarget, tPos, tipTitle;
                    if (row === 0) {
                        if ((endOfs.left - 12) <= mouseOfs.left && mouseOfs.left <= endOfs.left) {
                            insertTarget = td;
                            if (insertTarget.next().length > 0) {
                                tPos = { left: endOfs.left - 4, top: ofs.top - 12 };
                                tipTitle = eConfig.table.insertCol;
                            }
                        } else if ((ofs.left - 12) <= mouseOfs.left && mouseOfs.left <= (ofs.left + 12)) {
                            insertTarget = td.prev();
                            if (insertTarget.length > 0) {
                                tPos = { left: ofs.left - 4, top: ofs.top - 12 };
                                tipTitle = eConfig.table.insertCol;
                            }
                        }
                    }
                    if (col === 0 && mouseOfs.left <= (ofs.left + 20)) {
                        if ((endOfs.top - 12) <= mouseOfs.top && mouseOfs.top <= endOfs.top) {
                            insertTarget = td.parent();
                            tPos = { left: ofs.left - 5, top: endOfs.top - 12 };
                            tipTitle = eConfig.table.insertRow;
                        } else if ((ofs.top - 12) <= mouseOfs.top && mouseOfs.top <= (ofs.top + 12)) {
                            var prevRow = td.parent().prev();
                            if (prevRow.length > 0) {
                                insertTarget = prevRow;
                                tPos = { left: ofs.left - 5, top: ofs.top - 12 };
                                tipTitle = eConfig.table.insertRow;
                            }
                        }
                    }
                    if (insertTarget && tPos) {
                        if (insertTarget[0].tagName === "TR") {
                            if (insertTarget.children().first().attr("index") !== "0") {
                                return false;
                            }
                        }
                        _this._showAdd(insertTarget, tPos, tipTitle);
                    } else {
                        _this._hideAdd();
                    }
                },
                mousedown: function (e) {
                    stopDefaultctxMenu();
                    if (navigator.userAgent.indexOf("Firefox") > 0) {
                        document.designMode = "on";
                        document.execCommand('enableObjectResizing', false, 'false');
                        document.designMode = "off";
                    }
                    _this.clearSelected(true); //清空现在 
                    _this.clickTd = $(this).addClass("k_edit_selected_td_shadow");
                    if (e.which === 3) {
                        stopDefaultctxMenu();
                        return false;
                    }
                    mutilSelect = false;
                    var dragOpts,
                        $body = _getBody();
                    if (splitXPos || splitYPos) {
                        dragOpts = {
                            nameSpace: 'dragsplit', //命名空间，一个对象可以绑定多种拖动方式
                            which: 1, //鼠标键码，是否左键1,右键3 才能触发拖动，默认左右键均可
                            cursor: 'move',
                            axis: 'h',
                            onStartDrag: function (args) { //开始拖动
                                _this.edit._onChange();
                            },
                            onStopDrag: function (args) {
                                /***偏移量***/
                                var state = args.state;
                                var moveData = state._data;
                                var leftOffset = moveData.leftOffset;
                                var topOffset = moveData.topOffset;
                                var data = state.target.data("data");
                                var tableOfs = _this.jqObj.offset();
                                var putUndo = false;
                                if (leftOffset !== 0) {
                                    var compareXpoit = data;
                                    var trArray = _this.tbody.children();
                                    var startx = compareXpoit - 5;
                                    var endx = compareXpoit + 5;
                                    trArray.each(function () {
                                        $(this).children().each(function () {
                                            var td = $(this);
                                            var outerWidth = td.outerWidth();
                                            var endPoit = Math.round( td.offset().left );
                                            var startPoit = endPoit + outerWidth;
                                            var innerWidth, newWidth;
                                            if (startPoit <= endx && startPoit >= startx) {
                                                innerWidth = td.data("width");
                                                newWidth = innerWidth + leftOffset;
                                                td.data("width", newWidth).attr("w", newWidth);
                                                return true;
                                            }
                                            if (endPoit >= startx && endPoit <= endx) {
                                                innerWidth = td.data("width");
                                                newWidth = innerWidth - leftOffset;
                                                td.data("width", newWidth).attr("w", newWidth);
                                                return false;
                                            }
                                            if (endPoit > endx) {
                                                return false;
                                            }
                                        });
                                    });
                                    _this.onlyUpdateWidth = true;
                                    _this.setSize();
                                    _this.onlyUpdateWidth = false;
                                    putUndo = true;
                                } else if (topOffset !== 0) {
                                    if (data.targetRow.length > 0) {
                                        var rowspanTds = _this._getRowspanTds(data.targetRow);
                                        data.targetRow.children().each(function (i) {
                                            var td = $(this);
                                            var height = td.data("height") + topOffset;
                                            td.data("height", height).attr("h", height);
                                        });
                                        Object.keys(rowspanTds).forEach(function (key) {
                                            var td = rowspanTds[key];
                                            var height = td.data("height") + topOffset;
                                            td.data("height", height).attr("h", height);
                                        });
                                    }
                                    _this.onlyUpdateHeight = true;
                                    _this.setSize();
                                    _this.onlyUpdateHeight = false;
                                    putUndo = true;
                                }
                                state.target.remove();
                                splitLine = undefined;
                                if (putUndo) {
                                    _this.edit._putUndo();
                                }
                                _this.edit.moveToEnd(_this.clickTd);
                            }
                        };
                    } else {
                        mutilSelect = true;
                    }
                    if (splitXPos) { //列宽拖动 
                        //避免出现滚动条影响坐标
                        var top = _this.table.offset().top;
                        var bHeight = $body.height();
                        var diff = bHeight - (top + _this.height);
                        var sliptHeight = _this.height;
                        if(diff < 1){
                            sliptHeight = sliptHeight + diff;
                        }                       
                        splitLine = $("<div style='cursor:w-resize;left:" + splitXPos.left + "px;top:" + top + "px;position:absolute;height:" + sliptHeight + "px;width:2px;border-left:1px solid #FF000D;z-index:999999'/>");
                        splitLine.appendTo($body);
                        splitLine.data("data", splitXPos.left);
                        dragOpts.cursor = "w-resize";
                    } else if (splitYPos) { //行高拖动
                        splitYPos["left"] = _this.table.offset().left;
                        dragOpts["axis"] = "v";
                        splitLine = $("<div style='cursor:s-resize;left:" + splitYPos.left + "px;top:" + splitYPos.top + "px;position:absolute;height:3px;width:" + _this.table.outerWidth() + "px;border-top:1px solid #FF000D;z-index:99999999'/>");
                        splitLine.appendTo($body);
                        dragOpts.cursor = "s-resize";
                        splitLine.data("data", {
                            "targetRow": targetRow
                        });
                    }
                    if (splitLine) {
                        dragOpts["onStartDrag"] = function () {
                            //_this.table.attr("contenteditable","false");
                            _this.edit.moveToEnd(_this.clickTd);
                            undoData = _this.edit._makeUndoDataByFocus();
                        };
                        dragOpts["onMouseUp"] = function () {
                            splitLine.remove();
                            splitLine = undefined;
                            _this.edit.moveToEnd(_this.clickTd);
                        };
                        splitLine.draggable(dragOpts).trigger("mousedown.dragsplit", {
                            pageX: e.pageX,
                            pageY: e.pageY,
                            which: e.which
                        });
                        _this.menu.hide();
                        _this.$splitLine = splitLine;
                    }
                    _this.menu.hide();
                },
                click: function () {
                    return false;//避免冒泡edit.$input.click
                },
                dblclick: function () {
                    if (_this.clickTd) {
                        var pEl = _this.clickTd.children("p");
                        _this.edit.createCrossRange(pEl.first(), pEl.last());
                        _this.edit.saveUserRange();
                        //console.log("td dblclick >>>>>>>>>>>>>>");
                    }
                }
            };
            this.tdEvents = tdEvents;
        }
        return this.tdEvents;
    },
    hideMenu: function () {
        if (this.menu) {
            this.menu.hide();
        }
    },
    selectAllTd: function (left, top) {
        var _this = this;
        var trs = this.tbody.children();
        this.clickTd = trs.first().children().first();
        _this.selectTdArray = [];
        trs.each(function (i) {
            var tr = $(this);
            tr.children().each(function (j) {
                var td = $(this);
                var bgColor = td.css("background-color");
                td.css("background-color", _this.selectBackground).addClass("k_edit_table_selected_td");
                td.attr("bgcolor", bgColor);
                _this.selectTdArray.push(td);
                _this.mutilSelectBackground[td.attr("row") + "_" + td.attr("col")] = {
                    "td": td,
                    "background": bgColor
                };
            });
        });
        this.showMenu({
            pageX: left,
            pageY: top,
            mutils: true
        });
    },
    _showAnchor: function (args, ofs, endOfs, mouseOfs) {
        var _this = this;
        if (!this.$anchor) {
            this.$anchor = _getBody().children("#k_edit_table_anchor");
            if (this.$anchor.length === 0) {
                var $anchor = $("<div id='k_edit_table_anchor' title='" + eConfig.table.anchorTitle + "' style='cursor:pointer;background:#none;width:14px;height:14px;top:-1000px;position:absolute;z-index:9999999999;display:none;'><i class='fa fa-down-hand'></i></div>");
                this.$anchor = $anchor.appendTo(_getBody()).click(function () {
                    var $t = $(this);
                    var tabObj = $t.data("table");
                    var menuPos = $t.data("menuPos");
                    tabObj.selectAllTd(menuPos.left, menuPos.top);
                    $t.removeData("table");
                    $t.removeData("menuPos");
                    $t.hide();
                    tabObj.edit.clickActivedObject = tabObj;
                });
            }
        }
        this.$anchor.data("table", this);
        var pos = {};
        var cls = "";
        if (args.row === 0) { //第一行
            pos.top = ofs.top - 20;
            pos.left = mouseOfs.left;
            cls = 'fa-down-hand';
        } else if (args.isLastRow) { //最后一行
            pos.top = endOfs.top;
            pos.left = mouseOfs.left;
            cls = 'fa-hand-o-up';
        } else if (args.col === 0) {
            pos.left = ofs.left - 20;
            pos.top = mouseOfs.top;
            cls = 'fa-hand-o-right';
        } else if (args.isLastCol) {
            pos.left = endOfs.left;
            pos.top = mouseOfs.top;
            cls = 'fa-hand-o-left';
        }
        this.$anchor.css(pos).children("i").attr("class", "fa " + cls);
        this.$anchor.show().data("menuPos", ofs);
        clearTimeout(this.anchorHideTimer);
        this.anchorHideTimer = setTimeout(function () {
            if (_this.$anchor) {
                _this.$anchor.hide();
                _this.$anchor.removeData("table");
                _this.$anchor.removeData("menuPos");
            }
        }, 2500);
    },
    _hideAnchor: function () {
        if (this.$anchor) {
            this.$anchor.hide();
            this.$anchor.removeData("table");
            this.$anchor.removeData("menuPos");
        }
    },
    _getRowspanTds: function (targetRow) {
        var rowEndIdx = parseInt(targetRow.attr("id").replace("row_", ""));
        var colRec = {};
        var prevRow = targetRow.prev();
        while (prevRow.length > 0) {
            var childs = prevRow.children();
            for (var i = 0, len = childs.length; i < len; ++i) {
                var td = $(childs[i]);
                var index = td.attr("index");
                var rowspan = td.attr("rowspan");
                if (rowspan && !colRec[index]) {
                    var rowNum = parseInt(td.attr("row"));
                    var rowIdx = rowNum + parseInt(rowspan) - 1;
                    if (rowEndIdx <= rowIdx) {
                        colRec[index] = td;
                    }
                }
            }
            prevRow = prevRow.prev();
        }
        return colRec;
    },
    css2Siblings: function (td) {
        var prevTd = td.prev();
        var nextTd = td.next();
        var row = td.parent();
        var prevRow = row.prev();
        //var nextRow = row.next();
        var borderTop = td.css("border-top");
        var borderRight = td.css("border-right");
        var borderBottom = td.css("border-bottom");
        var borderLeft = td.css("border-left");
        nextTd.css("border-left", borderRight);
        prevTd.css("border-right", borderLeft);
        var index = parseInt(td.attr("index"));
        prevRow.children().each(function () {
            var _td = $(this);
            var idx = parseInt(_td.attr("index"));
            if (index === idx) {
                _td.css("border-bottom", borderTop);
                return false;
            }
            if (idx > index) {
                return false;
            }
        });
        nextTd.children().each(function () {
            var _td = $(this);
            var idx = parseInt(_td.attr("index"));
            if (index === idx) {
                _td.css("border-top", borderBottom);
                return false;
            }
            if (idx > index) {
                return false;
            }
        });
    },
    cssSubscribe: function (params) {
        var css = params["css"];
        var _this = this;
        //全表            
        if (params["target"] === "1") {
            var trs = this.table.css(css).children().children();
            var trLength = trs.length - 1;
            trs.each(function (i) {
                var tr = $(this);
                var tds = tr.children();
                var tdLength = tds.length - 1;
                tds.each(function (j) {
                    var td = $(this);
                    if (i === 0 || i === trLength) {
                        if (i === 0) {
                            td.css("border-top", css["border-top"]);
                        } else {
                            td.css("border-bottom", css["border-bottom"]);
                        }
                        if (j === 0) {
                            td.css("border-left", css["border-left"]);
                        } else if (j === tdLength) {
                            td.css("border-right", css["border-right"]);
                        }
                    } else {
                        if (j === 0) {
                            td.css("border-left", css["border-left"]);
                        } else if (j === tdLength) {
                            td.css("border-right", css["border-right"]);
                        }
                    }
                });
            });
        } else {
            if ($.isEmptyObject(this.mutilSelectBackground)) {
                this.clickTd.css(css);
                this.css2Siblings(this.clickTd);
            } else {
                this.foreachSeletedTds(function (rec) {
                    rec["td"].css(css);
                    _this.css2Siblings(rec["td"]);
                });
            }
        }
        clearTimeout(this.reSizeTimer);
        this.reSizeTimer = setTimeout(function () {
            _this.reSize();
        }, 300);
    },
    clickSubscribe: function (edit) {
        this.clearSelected(true);
        this.menu.hide();
    },
    makeSelectedUi: function () {
        if (!this.clickTd) {
            return;
        }
        var row0 = parseInt(this.clickTd.attr("row"));
        var col0 = parseInt(this.clickTd.attr("index"));
        var row1 = parseInt(this.movingTd.attr("row"));
        var col1 = parseInt(this.movingTd.attr("index"));
        var rowspan = this.movingTd.attr("rowspan");
        var colspan = this.movingTd.attr("colspan");
        if(rowspan){
            row1 = row1 + parseInt(rowspan) - 1;
        }
        if(colspan){
            col1 = col1 + parseInt(colspan) - 1;
        }
        this.clearSelected();
        var _this = this;
        var startRow, startCol, endRow, endCol;
        if (row1 > row0) {
            startRow = row0;
            endRow = row1;
        } else {
            startRow = row1;
            endRow = row0;
        }
        if (col1 > col0) {
            startCol = col0;
            endCol = col1;
        } else {
            startCol = col1;
            endCol = col0;
        }
        _this.selectTdArray = [];
        this.tbody.children().each(function (i) {
            if (i < startRow || i > endRow) {
                return true;
            }
            var tr = $(this);
            tr.children().each(function (j) {
                var td = $(this);
                var colIdx = parseInt(td.attr("index"));
                if (colIdx < startCol || colIdx > endCol) {
                    return true;
                }
                var bgColor = td.css("background-color");
                td.css("background-color", _this.selectBackground).addClass("k_edit_table_selected_td");
                td.attr("bgcolor", bgColor);
                _this.selectTdArray.push(td);
                _this.mutilSelectBackground[td.attr("row") + "_" + td.attr("col")] = {
                    "td": td,
                    "background": bgColor
                };
            });
        });
    },
    showSplitMerge: function (txt) {
        var tr = this.menu.jqObj.find("#_split_merge_td_").show();
        var $a = tr.find("a").text(txt);
        if (txt === eConfig.table.splitTd) {
            $a.data("flag", "splitFn");
        } else {
            $a.data("flag", "mergeFn");
        }
    },
    hideSplitMerge: function () {
        this.menu.jqObj.find("#_split_merge_td_").hide();
    },
    showMenu: function (e) {
        this.hideSplitMerge();
        var ofs = {
            top: e.pageY,
            left: e.pageX
        };
        var i, j, len;
        var body = _getBody();
        var bodyHeight = body.height();
        var bodyWidth = body.width();
        var useWidth = bodyWidth - ofs.left;
        if (useWidth < 300) {
            ofs.left = bodyWidth - 310;
        }
        var useHeight = bodyHeight - ofs.top;
        if (useHeight < 200) {
            ofs.top = ofs.top - 200;
        }
        this.menu.show(ofs).setTarget(this);
        var chkTable = this.menu.jqObj.find("#_target_table_1"); //
        var chkTd = this.menu.jqObj.find("#_target_cell_1"); //
        if (e.mutils) {
            chkTable.removeAttr("checked");
            chkTd.prop("checked", "checked").prop("disabled", false);
        } else {
            chkTable.prop("checked", "checked").prop("disabled", false);
            chkTd.removeAttr("checked");
        }
        if ($.isEmptyObject(this.mutilSelectBackground)) {
            if (this.clickTd.attr("colspan") || this.clickTd.attr("rowspan")) {
                this.showSplitMerge(eConfig.table.splitTd);
            }
        } else {
            var _this = this,
                isShow = true;
            //检查是连续的可合并的单元格集合 
            /*****每一行、列都必须有相同数量的td才能合并******/
            var colTdCounter = {};
            var rowTdCounter = {};
            this.foreachSeletedTds(function (rec) {
                var td = rec.td;
                var col = parseInt(td.attr("index"));
                var row = parseInt(td.attr("row"));

                var rowspan = td.attr("rowspan");
                var colspan = td.attr("colspan");
                var rspan = 0,
                    clspan = 0;
                if (rowspan) {
                    rspan = parseInt(rowspan) - 1;
                }
                if (colspan) {
                    clspan = parseInt(colspan) - 1;
                }
                if (colTdCounter[col]) {
                    colTdCounter[col] = colTdCounter[col] + 1 + rspan;
                } else {
                    colTdCounter[col] = 1 + rspan;
                }
                if (rowTdCounter[row]) {
                    rowTdCounter[row] = rowTdCounter[row] + 1 + clspan;
                } else {
                    rowTdCounter[row] = 1 + clspan;
                }
                var tmp = rspan;
                while (tmp > 0) {
                    row = row + 1;
                    if (rowTdCounter[row]) {
                        rowTdCounter[row] = rowTdCounter[row] + 1 + clspan;
                    } else {
                        rowTdCounter[row] = 1 + clspan;
                    }
                    tmp = --tmp;
                }
                tmp = clspan;
                while (tmp > 0) {
                    col = col + 1;
                    if (colTdCounter[col]) {
                        colTdCounter[col] = colTdCounter[col] + 1 + rspan;
                    } else {
                        colTdCounter[col] = 1 + rspan;
                    }
                    tmp = --tmp;
                }
            });
            //这里的逻辑有问题                
            var count, idx, c;
            var keyArray = Object.keys(colTdCounter);
            for (i = 0, len = keyArray.length; i < len; ++i) {
                idx = parseInt(keyArray[i]);
                if (i < len - 1) {
                    if (idx !== (parseInt(keyArray[i + 1]) - 1)) {
                        isShow = false;
                        break;
                    }
                }
                c = colTdCounter[idx];
                if (!count) {
                    count = c;
                } else {
                    if (count !== c) {
                        isShow = false;
                        break;
                    }
                }
            }
            if (isShow) {
                count = undefined;
                keyArray = Object.keys(rowTdCounter);
                for (j = 0, len = keyArray.length; j < len; ++j) {
                    idx = parseInt(keyArray[j]);
                    if (j < len - 1) {
                        if (idx !== (parseInt(keyArray[j + 1]) - 1)) {
                            isShow = false;
                            break;
                        }
                    }
                    c = rowTdCounter[idx];
                    if (!count) {
                        count = c;
                    } else {
                        if (count !== c) {
                            isShow = false;
                            break;
                        }
                    }
                }
                if (isShow) {
                    this.showSplitMerge(eConfig.table.megerTd);
                }
            }
        }
    },
    clearClickTd: function () {
        if (this.clickTd) {
            //console.log(" clearClickTd clearClickTd clearClickTd");
            this.clickTd.removeClass("k_edit_selected_td_shadow");
            this.clickTd = undefined;
        }
    },
    setClickTd: function (td) {
        this.clearClickTd();
        td.addClass("k_edit_selected_td_shadow");
        this.clickTd = td;
    },
    foreachSeletedTds: function (fn) {
        var _this = this;
        var hasLoop = false;
        Object.keys(this.mutilSelectBackground).forEach(function (key) {
            fn(_this.mutilSelectBackground[key]);
            hasLoop = true;
        });
        return hasLoop;
    },
    clearSelected: function (clearClickTd) {
        if (clearClickTd) {
            this.clearClickTd();
        }
        var _this = this;
        this.foreachSeletedTds(function (rec) {
            var bgColor = rec["td"].css("background-color"); //selectBackground
            var hexColor = bgColor.toHexColor();
            if (hexColor === _this.selectBackground) {
                rec["td"].css("background-color", rec["background"]);
            }
        });
        this.mutilSelectBackground = {};
        this.edit.clearSelectedTd();
    },
    /**
     * 提取td大小,保存到 data
     * * */
    saveSize: function () {
        this.tbody.children().each(function (r) {
            var tr = $(this).attr("id", "row_" + r);
            tr.children().each(function (c) {
                var td = $(this);
                td.attr("col", c).attr("row", r);
                var w = td.innerWidth();
                var h = td.innerHeight();
                td.data("width", w).attr("w", w);
                td.data("height", h).attr("h", h);
            });
        });
    },
    /***
     * 根据 data(widht/height)设置大小
     * ***/
    setSize: function (exeIdm) {
        var _this = this;
        this.table.width("auto");
        this.table.height("auto");
        var trArray = this.tbody.children();
        trArray.each(function (i) {
            var tr = $(this);
            var tdArr = tr.children();
            tdArr.each(function () {
                var td = $(this);
                if (!_this.onlyUpdateWidth) {
                    var h = td.data("height");
                    if (h < 24) {
                        td.css("line-height", (h - 2) + "px");
                    } else {
                        td.css("line-height", "21px");
                    }
                    td.innerHeight(h);
                }
                if (!_this.onlyUpdateHeight) {
                    var w = td.data("width");
                    td.innerWidth(w);
                }
            });
        });
        var f = function () {
            var w = _this.table.outerWidth();
            var h = _this.table.outerHeight();
            _this.height = h;
            _this.width = w;
            _this.saveSize();
        };
        if (exeIdm) {
            f();
        } else {
            setTimeout(f, 2);
        }
    },
    /**
     * saveSize(提取真是大小) >>> setSize
     * **/
    reSize: function (exeIdm) {
        this.saveSize();
        var _this = this;
        if (exeIdm) {
            _this.setSize(exeIdm);
        } else {
            setTimeout(function () {
                _this.setSize(exeIdm);
            }, 10);
        }
    },
    appendTo: function (target) {
        var uuid = $B.generateDateUUID();
        this["id"] = uuid;
        this.table.appendTo(target).attr("id", uuid);
        var _this = this;
        setTimeout(function () {
            _this.reSize();
            var selection = _this.edit.getDomSelection();
            try {
                selection.removeAllRanges();
            } catch (e) { }
        }, 2);
        this.contenteditableTxt = this.table.parent();
        this.table.mouseleave(function () {
            _this.contenteditableTxt.removeAttr("contenteditable");
        });
    },
    _createTr: function (props, css) {
        var tr = $("<tr/>");
        if (props) {
            tr.attr(props);
        }
        if (css) {
            tr.css(css);
        }
        return tr;
    },
    _createTd: function (props, css) {
        var td = $("<td id='" + getUUID() + "' class='k_box_size'><p style='-webkit-margin-before: 0px;-webkit-margin-after: 0px;-webkit-margin-start: 0px;-webkit-margin-end: 0px;' id='" + getUUID() + "'><span style='" + eConfig.defaultStyle + "' id='" + getUUID() + "'>\u200B</span></p></td>");
        td.children("p").css(eConfig.pElementCss);
        if (props) {
            td.attr(props);
        }
        if (css) {
            td.css(css);
        }
        return td;
    },
    /**
     * l左侧插入列  
     * r右侧插入列
     * **/
    insertColFn: function (prs) {
        this.edit._onChange();
        //console.log("insertColFn insertColFn insertColFn-----> ");
        var index = parseInt(this.clickTd.attr("index"));
        var newTd,
            events = this._getTdEvents();
        if (prs === "r") {
            var sp = this.clickTd.attr("colspan");
            if (sp) {
                index = index + parseInt(sp) - 1;
            }
        }
        var colWidth = 80;
        var trs = this.tbody.children();
        var _this = this;
        trs.each(function () {
            var tr = $(this);
            tr.children().each(function () {
                var td = $(this);
                var idx = parseInt(td.attr("index"));
                var colspan = td.attr("colspan");
                var startCol = parseInt(td.attr("col"));
                var style = td.attr("style");
                var row = td.attr("row");
                var isFined, insertFn, nextIdx, endIdx;
                if (prs === "l") { //左边插入
                    insertFn = "insertAfter";
                    if (colspan) {
                        colspan = parseInt(colspan);
                        endIdx = idx + colspan;
                        nextIdx = endIdx;
                    } else {
                        nextIdx = idx + 1;
                    }
                    if (idx === index) {
                        insertFn = "insertBefore";
                        isFined = true;
                    } else if (nextIdx === index) {
                        isFined = true;
                    }
                    if (isFined) {
                        newTd = _this._createTd({
                            "tabindex": "0",
                            "row": row,
                            "col": startCol,
                            "index": nextIdx
                        }, eConfig.table.tdCss);
                        newTd.attr("style", style);
                        newTd.width(colWidth).height("auto");
                        newTd[insertFn](td).on(events);
                        if (insertFn === "insertAfter") {
                            startCol = startCol + 1;
                            newTd.attr({
                                "col": startCol,
                                "index": nextIdx
                            });
                        } else {
                            newTd.attr({
                                "col": idx,
                                "index": idx
                            });
                        }
                        return false;
                    } else {
                        if (colspan) {
                            if (index >= idx && index <= endIdx) {
                                td.attr("colspan", colspan + 1);
                                return false;
                            }
                        } else {
                            if (idx >= index) {
                                return false;
                            }
                        }
                    }
                } else { //右侧插入                        
                    insertFn = "insertAfter";
                    if (colspan) {
                        colspan = parseInt(colspan);
                        endIdx = idx + colspan;
                        isFined = (endIdx - 1) === index;
                    } else {
                        isFined = idx === index;
                    }
                    if (!isFined) {
                        if ((idx - 1) === index) {
                            insertFn = "insertBefore";
                            isFined = true;
                        } else if (td.next().length === 0) {
                            insertFn = "insertAfter";
                            isFined = true;
                        }
                    }
                    if (isFined) {
                        newTd = _this._createTd({
                            "tabindex": "0",
                            "row": row,
                            "col": 0,
                            "index": 0
                        }, eConfig.table.tdCss);
                        newTd.attr("style", style);
                        newTd.width(colWidth).height("auto");
                        newTd[insertFn](td).on(events);
                        if (insertFn === "insertAfter") {
                            startCol++;
                            newTd.attr({
                                "col": startCol,
                                "index": idx + 1
                            });
                        } else {
                            newTd.attr({
                                "col": startCol,
                                "index": idx
                            });
                        }
                        return false;
                    } else {
                        if (colspan) {
                            if (index >= idx && index < endIdx) {
                                td.attr("colspan", colspan + 1);
                                return false;
                            }
                        } else {
                            if (idx >= index) {
                                return false;
                            }
                        }
                    }
                }
            });
        });
        this.resetTableIndex();
        this.reSize(true);
        this.edit.moveToEnd(newTd);
    },
    /**
     * t上方插入行
     * b下方插入行
     * ***/
    insertRowFn: function (prs) {
        this.edit._onChange();
        var currentRow = this.clickTd.parent();
        var rowIdx = parseInt(this.clickTd.attr("row"));
        var _this = this;
        var newTr = this._createTr({
            "id": "row_0"
        });
        var newTd, i, j, len;
        if (prs === "t") { //上方插入
            newTr.attr("id", "row_" + rowIdx);
            newTr.insertBefore(currentRow);
        } else {
            var rowspan = this.clickTd.attr("rowspan");
            if (rowspan) {
                rowspan = parseInt(rowspan) - 1;
                while (rowspan > 0) {
                    currentRow = currentRow.next();
                    rowspan--;
                }
                rowIdx = parseInt(currentRow.attr("id").replace("row_", ""));
            }
            rowIdx++;
            newTr.attr("id", "row_" + rowIdx);
            newTr.insertAfter(currentRow);
        }
        var currentRowIndex = rowIdx;
        /***更新后面的id行号***/
        var nextRow = newTr.next();
        while (nextRow.length > 0) {
            rowIdx++;
            nextRow.attr("id", "row_" + rowIdx);
            nextRow.children().attr("row", rowIdx);
            nextRow = nextRow.next();
        }
        //分析需要插入多少个td,提前需要rowspan+1的单元格
        var prevRow = newTr.prev();
        var rowspanTds = [];
        var notCreateTd = {};
        var td, rspan;
        while (prevRow.length > 0) {
            var ridx = parseInt(prevRow.attr("id").replace("row_", ""));
            var childs = prevRow.children();
            for (i = 0, len = childs.length; i < len; ++i) {
                td = $(childs[i]);
                var tdIdx = parseInt(td.attr("index"));
                if (!notCreateTd[tdIdx]) {
                    rspan = td.attr("rowspan");
                    if (rspan) {
                        rspan = parseInt(rspan) - 1;
                        var tmp = ridx + rspan;
                        if (tmp >= currentRowIndex) {
                            notCreateTd[tdIdx] = true;
                            var colspan = td.attr("colspan");
                            if (colspan) {
                                colspan = parseInt(colspan) - 1;
                                while (colspan > 0) {
                                    tdIdx++;
                                    notCreateTd[tdIdx] = true;
                                    colspan--;
                                }
                            }
                            rowspanTds.push(td);
                        }
                    }
                }
            }
            prevRow = prevRow.prev();
        }
        var startIndex = 0;
        var colIdx = 0;
        var style = this.clickTd.attr("style");
        var events = this._getTdEvents();
        while (startIndex < this.colNum) {
            if (!notCreateTd[startIndex]) {
                newTd = _this._createTd({
                    "tabindex": "0",
                    "row": currentRowIndex,
                    "col": colIdx,
                    "index": startIndex
                }, eConfig.table.tdCss);
                newTd.attr("style", style);
                newTd.width("auto").height("auto").on(events);
                newTd.appendTo(newTr);
                colIdx++;
            }
            startIndex++;
        }
        for (j = 0, len = rowspanTds.length; j < len; ++j) {
            td = rowspanTds[j];
            rspan = parseInt(td.attr("rowspan")) + 1;
            td.attr("rowspan", rspan);
        }
        this.reSize(true);
        this.rowNum++;
        if (newTd) {
            this.edit.moveToEnd(newTd);
        }
    },
    /**删除内容**/
    deleteContentFn: function (prs) {
        this.edit._onChange();
        var activeTd;
        this.foreachSeletedTds(function (rec) {
            var td = rec.td;
            td.find("a").remove();
            activeTd = td.html("\u200B");
        });
        this.clearSelected();
        this.edit.moveToEnd(activeTd);
        this.setClickTd(activeTd);
    },
    insertImageFn: function () {
        this.edit._onChange();
        this.edit.openInsertImageWindow("picture", {
            undo: true,
            needRange: false
        });
    },
    insertFileFn: function () {
        this.edit._onChange();
        this.edit.openInsertFileWindow("upload", {
            undo: true,
            needRange: false
        });
    },
    deleteRowFn: function (prs) {
        this.edit._onChange();
        var deleteRow = {};
        var _this = this;
        var hasLoop = this.foreachSeletedTds(function (rec) {
            var r = parseInt(rec.td.attr("row"));
            var row = rec.td.parent();
            deleteRow[r] = row;
            var rspan = rec.td.attr("rowspan");
            if (rspan) {
                var curRow = row;
                rspan = parseInt(rspan) - 1;
                while (rspan > 0) {
                    r++;
                    deleteRow[r] = curRow.next();
                    curRow = deleteRow[r];
                    rspan--;
                }
            }
        });
        if (hasLoop) {
            var delKeys = Object.keys(deleteRow);
            if (delKeys.length === _this.rowNum) {
                _this.deleteTableFn();
            } else {
                delKeys.forEach(function (key) {
                    var row = deleteRow[key];
                    _this._removeRow(row);
                });
                _this._activedFirstTd();
            }
        } else {
            var delRow = this.clickTd.parent();
            if (_this.rowNum === 1) {
                _this.deleteTableFn();
            } else {
                _this._removeRow(delRow);
                _this._activedFirstTd();
            }
        }
    },
    _removeRow: function (row) {
        var curRowIndex = parseInt(row.attr("id").replace("row_", ""));
        var prevRow = row.prev();
        var rowSpanTdArray = [];
        var childs, i, len, td, h;
        var _this = this;
        while (prevRow.length > 0) {
            childs = prevRow.children();
            for (i = 0, len = childs.length; i < len; ++i) {
                td = $(childs[i]);
                var index = parseInt(td.attr("index"));
                var rowspan = td.attr("rowspan");
                var rowIdx = parseInt(td.attr("row"));
                if (rowspan) {
                    var rIdx = parseInt(rowspan) - 1 + rowIdx;
                    if (rIdx >= curRowIndex) {
                        rowSpanTdArray.push(td);
                    }
                }
            }
            prevRow = prevRow.prev();
        }
        var newTdRec = [];
        row.children().each(function (i) {
            td = $(this);
            var rowspan = td.attr("rowspan");
            if (rowspan) {
                var style = td.attr("style");
                newTdRec.push({
                    style: style,
                    content: td.html(),
                    height: td.data("height"),
                    index: parseInt(td.attr("index")),
                    rowspan: parseInt(rowspan),
                    colspan: td.attr("colspan")
                });
            }
        });
        var removeHeight = row.height();
        var nextRow = row.next();
        row.remove();
        for (i = 0, len = rowSpanTdArray.length; i < len; ++i) {
            td = rowSpanTdArray[i];
            h = td.data("height") - removeHeight;
            var rs = parseInt(td.attr("rowspan")) - 1;
            if (rs > 1) {
                td.attr("rowspan", rs);
            } else {
                td.removeAttr("rowspan");
            }
            td.innerHeight(h);
        }
        var events;
        len = newTdRec.length;
        if (len > 0) {
            events = this._getTdEvents();
        }
        for (i = 0; i < len; ++i) {
            var rec = newTdRec[i];
            td = _this._createTd({
                "tabindex": "0",
                "row": 0,
                "col": 0,
                "index": rec.index
            }, eConfig.table.tdCss);
            td.children("p").html(rec.content);
            td.attr("style", rec.style).attr("index", rec.index);
            var rspan = rec.rowspan - 1;
            if (rspan > 1) {
                td.attr("rowspan", rspan);
            }
            if (rec.colspan) {
                td.attr("colspan", rec.colspan);
            }
            h = rec.height - removeHeight;
            td.innerHeight(h).data("height", h).on(events);
            var idx = rec.index;
            if (idx === 0) {
                td.prependTo(nextRow);
            } else {
                idx = idx - 1;
                var childrens = nextRow.children();
                for (var k = 0, klen = childrens.length; k < klen; ++k) {
                    var targetTd = $(childrens[k]);
                    var _index = parseInt(targetTd.attr("index"));
                    if (idx === _index) {
                        td.insertAfter(targetTd);
                        break;
                    } else if (_index > idx) {
                        var prevTd = targetTd.prev();
                        if (prevTd.length > 0) {
                            td.insertAfter(prevTd);
                            break;
                        } else {
                            td.insertBefore(targetTd);
                            break;
                        }
                    } else {
                        var nextTd = targetTd.next();
                        if (nextTd.length === 0) {
                            td.insertAfter(targetTd);
                        }
                    }
                }
            }
        }
        this.reSize(true);
        this.rowNum--;
    },
    deleteColFn: function () {
        this.edit._onChange();
        var _this = this;
        var deleteColMap = {};
        var deleteColArray = [];
        var hasLoop = this.foreachSeletedTds(function (rec) {
            var col = parseInt(rec.td.attr("index"));
            if (!deleteColMap[col]) {
                deleteColMap[col] = true;
                deleteColArray.push(col);
                var colspan = rec.td.attr("colspan");
                if (colspan) {
                    colspan = parseInt(colspan) - 1;
                    while (colspan > 0) {
                        col++;
                        if (!deleteColMap[col]) {
                            deleteColMap[col] = true;
                            deleteColArray.push(col);
                        }
                        colspan--;
                    }
                }
            }
        });
        if (hasLoop) {
            if (deleteColArray.length === this.colNum) {
                _this.deleteTableFn();
            } else {
                for (var i = 0, len = deleteColArray.length; i < len; ++i) {
                    var rmTd = deleteColArray[i];
                    _this._removeCol(rmTd);
                }
                _this._activedFirstTd();
            }
        } else {
            if (_this.colNum === 1) {
                _this.deleteTableFn();
            } else {
                var col = parseInt(_this.clickTd.attr("index"));
                _this._removeCol(col);
                _this._activedFirstTd();
            }
        }
    },
    _activedFirstTd: function () {
        var activeTd = this.tbody.children().first().children().first();
        this.edit.moveToEnd(activeTd);
        this.mutilSelectBackground = {};
        this.selectTdArray = [activeTd];
    },
    _removeCol: function (colIdx) {
        var _resetIndexFn = function (nextTd) {
            while (nextTd.length > 0) {
                var index = parseInt(nextTd.attr("index")) - 1;
                nextTd.attr("index", index);
                nextTd = nextTd.next();
            }
        };
        var resetIndexTds = [];
        var trs = this.tbody.children();
        trs.each(function () {
            var tr = $(this);
            tr.children().each(function () {
                var td = $(this);
                var idx = parseInt(td.attr("index"));
                var endIdx = idx;
                var colspan = td.attr("colspan");
                if (colspan) {
                    colspan = parseInt(colspan);
                    var newSpan;
                    endIdx = idx + colspan - 1;
                    if (idx === colIdx) {
                        newSpan = colspan - 1;
                    } else if (endIdx === colIdx) {
                        newSpan = colspan - 1;
                    } else if (idx < colIdx && idx < endIdx) {
                        newSpan = colspan - 1;
                    }
                    if (newSpan) {
                        if (newSpan === 1) {
                            td.removeAttr("colspan");
                            resetIndexTds.push(td.next());
                            return false;
                        } else {
                            td.attr("colspan", newSpan);
                            resetIndexTds.push(td.next());
                            return false;
                        }
                    }
                } else {
                    if (idx === colIdx) {
                        resetIndexTds.push(td.next());
                        td.remove();
                        return false;
                    } else if (endIdx >= colIdx) {
                        resetIndexTds.push(td);
                        return false;
                    }
                }
            });
        });
        for (var i = 0, len = resetIndexTds.length; i < len; ++i) {
            _resetIndexFn(resetIndexTds[i]);
        }
        this.reSize(true);
        this.colNum--;
    },
    deleteTableFn: function () {
        if(this.edit.movingAcn){
            this.edit.movingAcn.hide();
        } 
        this.edit._onChange();
        var p = this.table.parent();
        var edit = this.edit;
        var tableId = this.table.attr("id");
        edit._deleteTable(tableId);
        p.html("<span style='" + eConfig.defaultStyle + "' id='" + tableId + "'>\u200B</span>");
        edit.createCrossRange(p, p);
        edit.moveToEnd(p);
    },
    mergeFn: function () {
        var rowspan = 0,
            colspan = 0,
            helper = 0,
            modifyTd,
            rowRec = {},
            colRec = {},
            _this = this;
        this.edit._onChange();
        this.edit._putUndo();
        this.foreachSeletedTds(function (rec) {
            var td = rec["td"];
            var row = parseInt(td.attr("row"));
            var col = parseInt(td.attr("index"));
            rowRec[row] = 1;
            colRec[col] = 1;
            rowspan = td.attr("rowspan");
            colspan = td.attr("colspan");
            var rspan = 0,
                clspan = 0;
            if (rowspan) {
                rspan = parseInt(rowspan) - 1;
                while (rspan > 0) {
                    row = ++row;
                    rowRec[row] = 1;
                    rspan = --rspan;
                }
            }
            if (colspan) {
                clspan = parseInt(colspan) - 1;
                while (clspan > 0) {
                    col = ++col;
                    colRec[col] = 1;
                    clspan = --clspan;
                }
            }
            if (helper === 0) {
                modifyTd = td;
            }
            helper = ++helper;
        });
        rowspan = Object.keys(rowRec).length;
        colspan = Object.keys(colRec).length;
        helper = 0;
        var w = 0;
        var heightRec = {};
        var widthRec = {};
        var removeTdArray = [];
        var keys;
        _this.foreachSeletedTds(function (rec) {
            var td = rec["td"];
            var col = td.attr("index");
            var row = td.attr("row");
            if (widthRec[row]) {
                widthRec[row] = widthRec[row] + td.outerWidth();
            } else {
                widthRec[row] = td.innerWidth();
            }
            if (heightRec[col]) {
                heightRec[col] = heightRec[col] + td.outerHeight();
            } else {
                heightRec[col] = td.innerHeight();
            }
            if (helper !== 0) {
                removeTdArray.push(td);
            }
            helper = ++helper;
        });
        for (var i = 0, len = removeTdArray.length; i < len; ++i) {
            removeTdArray[i].remove();
        }
        if (rowspan > 1) {
            keys = Object.keys(heightRec);
            modifyTd.attr("rowspan", rowspan).data("height", heightRec[keys[0]]);
        }
        if (colspan > 1) {
            keys = Object.keys(widthRec);
            modifyTd.attr("colspan", colspan).data("width", widthRec[keys[0]]);
        }
        this.setSize();
        //清空选择
        this.clearSelected();
        this.edit.moveToEnd(modifyTd);
    },
    splitFn: function () {
        this.edit._onChange();
        var _this = this;
        var colspan = _this.clickTd.attr("colspan");
        var rowCount = parseInt(_this.clickTd.attr("rowspan")) - 1;
        var idx = parseInt(_this.clickTd.attr("index"));
        var currentIdx = idx;
        //var row = this.clickTd.attr("row");
        var copyStyle = _this.edit._style2CssObject(this.clickTd, true);
        delete copyStyle.width;
        delete copyStyle.height;
        var events = this._getTdEvents();
        var avgWidth, count, td, i, len;
        if (colspan) {
            colspan = parseInt(colspan);
            avgWidth = _this.clickTd.data("width") / colspan;
            _this.clickTd.width(avgWidth).removeAttr("colspan");
            count = colspan - 1;
            var insertTarget = _this.clickTd;
            while (count > 0) {
                idx = idx + 1;
                td = this._createTd({
                    "tabindex": "0",
                    "row": 0,
                    "col": 0,
                    "index": idx
                }, eConfig.table.tdCss);
                count = --count;
                td.on(events).css($.extend(copyStyle, {
                    "width": avgWidth,
                    "height": "auto"
                }));
                insertTarget = td.insertAfter(insertTarget);
            }
        }
        if (rowCount) {
            var tdCount = 1; //需要创建的td数量
            if (colspan) {
                tdCount = colspan;
            }
            if (!avgWidth) {
                avgWidth = _this.clickTd.data("width") / colspan;
            }
            _this.clickTd.width(avgWidth).height("auto").removeAttr("rowspan");
            var tdRow = this.clickTd.parent();
            var currentRow = tdRow.next();
            var nextIdx = 0;
            var cFn = function () {
                td = _this._createTd({
                    "tabindex": "0",
                    "row": 0,
                    "col": 0,
                    "index": nextIdx
                }, eConfig.table.tdCss);
                td.on(events);
                nextIdx++;
                currentRow.append(td);
            };
            var targetTd, childArray, index, fined, tr, helper;
            while (rowCount > 0) {
                childArray = currentRow.children();
                len = childArray.length;
                if (len === 0) {
                    tdRow.children().each(cFn);
                } else {
                    for (i = 0; i < len; ++i) {
                        td = $(childArray[i]);
                        index = parseInt(td.attr("index"));
                        targetTd = undefined;
                        if (index >= idx) {
                            targetTd = td.prev();
                        } else if (td.next().length === 0) {
                            targetTd = td;
                        }
                        if (targetTd) {
                            fined = targetTd.length > 0;
                            tr = td.parent();
                            helper = 0;
                            count = tdCount;
                            nextIdx = currentIdx;
                            while (count > 0) {
                                if (fined) {
                                    td = _this._createTd({
                                        "tabindex": "0",
                                        "row": 0,
                                        "col": 0,
                                        "index": nextIdx
                                    }, eConfig.table.tdCss);
                                    targetTd = td.insertAfter(targetTd);
                                    targetTd.on(events).css($.extend(copyStyle, {
                                        "width": avgWidth,
                                        "height": "auto"
                                    }));
                                    nextIdx = nextIdx + 1;
                                } else { //第一列利用tr插入td
                                    td = _this._createTd({
                                        "tabindex": "0",
                                        "row": 0,
                                        "col": 0,
                                        "index": helper
                                    }, eConfig.table.tdCss.td);
                                    if (helper === 0) { //先tr preppend ，后target insertAfter
                                        td.on(events).css($.extend(copyStyle, {
                                            "width": avgWidth,
                                            "height": "auto"
                                        }));
                                        tr.prepend(td);
                                        targetTd = td;
                                    } else {
                                        targetTd = td.insertAfter(targetTd).on(events).css($.extend(copyStyle, {
                                            "width": avgWidth,
                                            "height": "auto"
                                        }));
                                    }
                                    helper = ++helper;
                                }
                                count = --count;
                            }
                            break;
                        }
                    }
                }
                currentRow = currentRow.next();
                rowCount = --rowCount;
            }
        }
        _this.edit.moveToEnd(this.clickTd);
        setTimeout(function () {
            _this.saveSize();
        }, 2);
    },
    remove: function () {    
        var i,len;
        if(this.$splitLine){
            this.$splitLine.remove();            
        }   
        if(this.$anchor){
            this.$anchor.hide();
        }
        if(this.$addBtn){
            this.$addBtn.hide();
        }
        this.jqObj.removeData("object"); 
        this.table.remove();
        this.destroy();
    },
    destroy: function () {
        for (var p in this) {
            if (this.hasOwnProperty(p)) {
                delete this[p];
            }
        }
    }
};
/**
 * 表格属性    
 * **/
function TableProps(edit) {
    $B.extend(this, TableProps); //继承父类 
    this.edit = edit;
    this.wrap = $("<div style='position: absolute;z-index: 99999999;display:none;background:#ffffff;padding:5px 6px;width:190px;border: 1px solid #E0E0E0;' class='k_box_shadow'></div>");
    this.jqObj = this.wrap;
    var form = $(eConfig.tablePropsForm);
    this.wrap.append(form);
    window["_TableProps_"] = this;
    this.target = undefined;
    this.wrap.appendTo(_getBody());
    var _this = this;
    form.find("._color_picker").click(function () {
        var $t = $(this);
        _this.color.show($t);
        return false;
    });
    this.color = new $B.ColorPicker(undefined, {
        update2Target: false,
        showCaret: false,
        positionFix: {
            top: 2,
            left: 1
        },
        change: function (val) {
            if (_this.target.selectBackground === val) {
                var tmp = [];
                for (var i = 0, len = val.length; i < len - 1; ++i) {
                    tmp.push(val[i]);
                }
                val = tmp.join() + "1";
            }
            this.css("background-color", val);
            if (this.attr("id") === "_border_color_picker") {
                _this.onChange();
            } else {
                _this.onChange(val);
            }
        }
    }).setValue("#A9CADD");
    this.color["name"] = "TableProps ColorPicker";
    form.find(".k_edit_border_wrap").children().click(function () {
        var seft = $(this);
        seft.addClass("activtd").siblings().removeClass("activtd");
        _this.onChange();
    });
    this.borderSize = form.find("#_border_size_opts_").on("change", function () {
        _this.onChange();
    });
    this.borderStyle = form.find("#_border_style_opts_").on("change", function () {
        _this.onChange();
    });
    form.find("#_split_merge_td_").children().click(function () {
        var $t = $(this).find("a");
        var callFn = $t.data("flag");
        if (_this.target[callFn]) {
            _this._makeUndoData();
            _this.target[callFn]();
        }
        _this.hide();
    });
    this.borderColor = $("#_border_color_picker");
    // this.backgroundColor = $("#_background_color_picker");
    this.jqObj = this.wrap;
    var tbody = form.children("tbody").children().on({
        mouseover: function () {
            var tr = $(this);
            if (tr.hasClass("_delete_op_tr")) {
                _this.showDeleteMenu(tr);
            } else if (tr.hasClass("_insert_op_tr")) {
                _this.showInsertMenu(tr);
            } else {
                _this.hideDeleteMenu();
                _this.hideInsertMenu();
            }
        }
    });
    this.wrap.click(function () {
        _this.color.hide();
    });
    var setting = this.wrap.find("._section_set_tr");
    setting.find("td").children("div").html("<i style='padding-right:20px;font-size:16px;' class='fa fa-exchange'></i>" + eConfig.label.setSectionWidth);
    setting.click(function () {
        var p = _this.target.jqObj.parent();
        while (p.length > 0) {
            if (p[0].tagName === "DIV") {
                break;
            }
            p = p.parent();
        }
        _this.edit.startPElement = p;
        _this.edit.endPElement = p;
        _this.edit.setSectionWidth();
        _this.hide();
    });
    this.resetSectionTr = this.wrap.find("._rection_reset_tr");
    this.resetSectionTr.find("td").children("div").html("<i style='padding-right:20px;font-size:16px;' class='fa fa-resize-horizontal'></i>" + eConfig.label.resetSectionWidth);
    this.resetSectionTr.click(function () {
        var p = _this.target.jqObj.parent();
        while (p.length > 0) {
            if (p[0].tagName === "DIV") {
                break;
            }
            p = p.parent();
        }
        _this.edit.startPElement = p;
        _this.edit.endPElement = p;
        _this.edit.resetSectionWidth();
        _this.hide();
    });
    this.wrap.mousedown(function () {
        stopDefaultctxMenu();
    });
    this.wrap.find("._rection_move_tr").click(function () {
        var p = _this.target.jqObj.parent();
        while (p.length > 0) {
            if (p[0].tagName === "DIV") {
                break;
            }
            p = p.parent();
        }
        var eles = [p];
        _this.edit._setMovingTargets(eles, false);
        _this.hide();
    });
}
TableProps.prototype = {
    constructor: TableProps,
    showInsertMenu: function (tr) {
        this.hideDeleteMenu();
        var ofs = tr.offset();
        var w = this.wrap.outerWidth();
        ofs.left = this.wrap.offset().left + w;
        var body = _getBody();
        var bodyHeight = body.height();
        if ((bodyHeight - ofs.top) < 160) {
            ofs.top = ofs.top - 138;
        }
        if (!this["insertMenu"]) {
            var _this = this; // 
            var wrap = $("<div style='position: absolute;z-index:99999999;background:#ffffff;padding:2px 3px;width:80px;' class='k_box_shadow k_edit_delete_op_wrap'></div>");
            $("<span>" + eConfig.table.insertRight + "</span>").appendTo(wrap).on("click", function () {
                _this.operatorFn("insertColFn", "r");
            });
            $("<span>" + eConfig.table.insertLeft + "</span>").appendTo(wrap).on("click", function () {
                _this.operatorFn("insertColFn", "l");
            });
            $("<span>" + eConfig.table.insertUp + "</span>").appendTo(wrap).on("click", function () {
                _this.operatorFn("insertRowFn", "t");
            });
            $("<span>" + eConfig.table.insertDown + "</span>").appendTo(wrap).on("click", function () {
                _this.operatorFn("insertRowFn", "d");
            });
            $("<span>" + eConfig.table.insertFile + "</span>").appendTo(wrap).on("click", function () {
                _this.operatorFn("insertFileFn");
            });
            $("<span>" + eConfig.table.insertImg + "</span>").appendTo(wrap).on("click", function () {
                _this.operatorFn("insertImageFn");
            });
            this["insertMenu"] = wrap.css(ofs).appendTo(body);
        } else {
            this["insertMenu"].css(ofs).show();
        }
    },
    hideInsertMenu: function (tr) {
        if (this["insertMenu"]) {
            this["insertMenu"].hide();
        }
    },
    showDeleteMenu: function (tr) {
        this.hideInsertMenu();
        var ofs = tr.offset();
        var w = this.wrap.outerWidth();
        ofs.left = this.wrap.offset().left + w;
        var body = _getBody();
        var bodyHeight = body.height();
        if ((bodyHeight - ofs.top) < 105) {
            ofs.top = ofs.top - 82;
        }
        if (!this["deleteMenu"]) {
            var _this = this;
            var wrap = $("<div style='position: absolute;z-index:99999999;background:#ffffff;padding:2px 3px;width:80px;' class='k_box_shadow k_edit_delete_op_wrap'></div>");
            $("<span>" + eConfig.table.removeContent + "</span>").appendTo(wrap).on("click", function () {
                _this.operatorFn("deleteContentFn");
            });
            $("<span>" + eConfig.table.removeRow + "</span>").appendTo(wrap).on("click", function () {
                _this.operatorFn("deleteRowFn");
            });
            $("<span>" + eConfig.table.removeCol + "</span>").appendTo(wrap).on("click", function () {
                _this.operatorFn("deleteColFn");
            });
            $("<span>" + eConfig.table.removeTable + "</span>").appendTo(wrap).on("click", function () {
                _this.operatorFn("deleteTableFn");               
            });
            this["deleteMenu"] = wrap.css(ofs).appendTo(_getBody());
        } else {
            this["deleteMenu"].css(ofs).show();
        }
    },
    //undo记录
    _makeUndoData: function () {
        this.target.edit.putUndoByFocus();
    },
    operatorFn: function (opFn, prs) {
        this.hide();
        if (typeof this.target[opFn] === "function") {
            this._makeUndoData();
            this.target[opFn](prs);
        }
    },
    hideDeleteMenu: function () {
        if (this["deleteMenu"]) {
            this["deleteMenu"].hide();
        }
    },
    onChange: function (backgroundColor) {
        var _tg = this.jqObj.find("input[type=radio]:checked").val();
        var border = this.jqObj.find(".k_edit_border_wrap").children(".activtd").attr("tg");
        var size = this.borderSize.val();
        var style = this.borderStyle.val();
        var borderColor = this.borderColor.css("background-color");
        var css = {};
        if (backgroundColor) {
            css["background-color"] = backgroundColor;
        }
        var val = size + "px " + style + " " + borderColor;
        if (border === "border") {
            css["border-left"] = val;
            css["border-top"] = val;
            css["border-right"] = val;
            css["border-bottom"] = val;
        } else {
            css[border] = val;
        }
        var params = {
            "target": _tg,
            "css": css
        };
        if (typeof this.target.cssSubscribe === "function") {
            this.target.cssSubscribe(params);
        }
    },
    hide: function () {
        //console.log("table hide >>>>>>>>>>>>>>>>>>>>>");
        this.wrap.hide();
        this.color.hide();
        this.hideDeleteMenu();
        this.hideInsertMenu();
        return this;
    },
    show: function (ofs) {
        this.hideDeleteMenu();
        this.hideInsertMenu();
        var bodyWidth = _getBody().width();
        var endPosX = ofs.left + 220;
        var diff = endPosX - bodyWidth;
        if (diff > 0) {
            ofs.left = ofs.left - diff;
        }
        this.wrap.css(ofs).show();
        this.color.hide();
        this._showOrHideOpt();
        return this;
    },
    setTarget: function (target) {
        this.target = target;
        this._showOrHideOpt();
        return this;
    },
    _showOrHideOpt: function () {
        if (this.target && this.target.jqObj) {
            var pleft = this.target.jqObj.parent().css("padding-left");
            if (pleft !== "0px") {
                this.resetSectionTr.show();
            } else {
                this.resetSectionTr.hide();
            }
        }
    }
};
window["TableProps"] = TableProps;